package com.example.chengzhengwei;

import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.hardware.usb.UsbDevice;
import android.hardware.usb.UsbManager;
import android.os.Build;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
import android.widget.Toast;

import androidx.annotation.RequiresApi;

import com.hoho.android.usbserial.driver.UsbSerialDriver;
import com.hoho.android.usbserial.driver.UsbSerialPort;
import com.hoho.android.usbserial.driver.UsbSerialProber;
import com.hoho.android.usbserial.util.SerialInputOutputManager;

import java.io.IOException;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class SerialPortHelper {
    private static final String TAG = "SerialPortHelper";
    private static final String ACTION_USB_PERMISSION = "com.example.chengzhengwei.USB_PERMISSION";

    private final Context context;
    private final UsbManager usbManager;
    private final Handler mainHandler;
    private final ExecutorService executor;

    private UsbSerialDriver serialDriver;
    private UsbSerialPort serialPort; // 新增 UsbSerialPort 用于操作
    private SerialInputOutputManager ioManager;

    private SerialPortListener listener;
    public boolean isConnected;

    public interface SerialPortListener {
        void onConnected();

        void onDisconnected();

        void onError(String message);

        void onDataReceived(byte[] data);
    }

    public SerialPortHelper(Context context) {
        this.context = context;
        this.usbManager = (UsbManager) context.getSystemService(Context.USB_SERVICE);
        this.mainHandler = new Handler(Looper.getMainLooper());
        this.executor = Executors.newSingleThreadExecutor();
        this.isConnected = false;
    }

    public void setListener(SerialPortListener listener) {
        this.listener = listener;
    }

    public void init() {
        IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION);
        filter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED);
        // 处理广播接收器注册标志问题
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
            context.registerReceiver(usbReceiver, filter, Context.RECEIVER_NOT_EXPORTED);
        } else {
            context.registerReceiver(usbReceiver, filter);
        }
    }

    public void release() {
        stopIoManager();
        closeConnection();
        try {
            context.unregisterReceiver(usbReceiver);
        } catch (Exception e) {
            Log.e(TAG, "Error unregistering receiver", e);
        }
        executor.shutdown();
    }

    public void connect() {
        List<UsbSerialDriver> drivers = UsbSerialProber.getDefaultProber().findAllDrivers(usbManager);
        if (drivers.isEmpty()) {
            showToast("未找到串口设备");
            if (listener != null) listener.onError("未找到串口设备");
            return;
        }

        serialDriver = drivers.get(0);
        UsbDevice device = serialDriver.getDevice();
        serialPort = serialDriver.getPorts().get(0); // 获取串口端口

        if (usbManager.hasPermission(device)) {
            openDevice();
        } else {
            Intent intent = new Intent(ACTION_USB_PERMISSION);
            intent.setComponent(new ComponentName(context.getPackageName(), usbReceiver.getClass().getName()));
            PendingIntent permissionIntent;
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
                permissionIntent = PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_IMMUTABLE);
            } else {
                permissionIntent = PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
            }
            usbManager.requestPermission(device, permissionIntent);
        }
    }

    public void disconnect() {
        stopIoManager();
        closeConnection();
        isConnected = false;
        if (listener != null) listener.onDisconnected();
    }

    public void sendData(String data) {
        if (!isConnected) {
            if (listener != null) listener.onError("串口未连接");
            return;
        }

        if (ioManager != null) {
            ioManager.writeAsync(data.getBytes());
        }
    }

    private void openDevice() {
        try {
            if (usbManager.openDevice(serialDriver.getDevice()) == null) {
                if (listener != null) listener.onError("无法连接到设备");
                return;
            }
            serialPort.open(usbManager.openDevice(serialDriver.getDevice())); // 使用 UsbSerialPort 的 open 方法
            serialPort.setParameters(115200, 8, UsbSerialPort.STOPBITS_1, UsbSerialPort.PARITY_NONE); // 修正符号引用

            startIoManager();

            isConnected = true;
            if (listener != null) listener.onConnected();
            showToast("串口已连接");
        } catch (IOException e) {
            Log.e(TAG, "Error opening device", e);
            closeConnection();
            if (listener != null) listener.onError("打开设备失败: " + e.getMessage());
        }
    }

    private void startIoManager() {
        stopIoManager();
        if (serialPort != null) { // 基于 UsbSerialPort
            ioManager = new SerialInputOutputManager(serialPort, new SerialInputOutputManager.Listener() {
                @Override
                public void onRunError(Exception e) {
                    Log.e(TAG, "IO manager error: " + e.getMessage());
                    stopIoManager();
                    mainHandler.post(() -> {
                        if (listener != null) listener.onError("IO管理器错误: " + e.getMessage());
                    });
                }

                @Override
                public void onNewData(byte[] data) {
                    mainHandler.post(() -> {
                        if (listener != null) listener.onDataReceived(data);
                    });
                }
            });

            executor.submit(ioManager);
        }
    }

    private void stopIoManager() {
        if (ioManager != null) {
            ioManager.stop();
            ioManager = null;
        }
    }

    private void closeConnection() {
        stopIoManager();
        try {
            if (serialPort != null) {
                serialPort.close(); // 使用 UsbSerialPort 的 close 方法
            }
        } catch (IOException e) {
            Log.e(TAG, "Error closing driver", e);
        }
        serialDriver = null;
        serialPort = null;
    }

    private final BroadcastReceiver usbReceiver = new BroadcastReceiver() {
        @RequiresApi(api = Build.VERSION_CODES.TIRAMISU)
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            if (action == null) return;

            switch (action) {
                case ACTION_USB_PERMISSION:
                    synchronized (this) {
                        UsbDevice device = intent.getParcelableExtra(UsbManager.EXTRA_DEVICE, UsbDevice.class);
                        if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) {
                            if (device != null) {
                                openDevice();
                            }
                        } else {
                            showToast("USB 权限被拒绝");
                            if (listener != null) listener.onError("USB 权限被拒绝");
                        }
                    }
                    break;

                case UsbManager.ACTION_USB_DEVICE_DETACHED:
                    UsbDevice device = intent.getParcelableExtra(UsbManager.EXTRA_DEVICE, UsbDevice.class);
                    if (device != null && device.equals(serialDriver.getDevice())) {
                        disconnect();
                    }
                    break;
            }
        }
    };

    private void showToast(String message) {
        mainHandler.post(() -> Toast.makeText(context, message, Toast.LENGTH_SHORT).show());
    }

    // 在 SerialPortHelper.java 中添加此方法
    public void sendBytes(byte[] data) {
        if (!isConnected) {
            if (listener != null) listener.onError("串口未连接");
            return;
        }

        if (ioManager != null) {
            ioManager.writeAsync(data);
        }
    }
}